package models

type BaseInfo struct {
	ID         string `json:"id"`
	CreateTime int64  `json:"create_time"`
	UpdateTime int64  `json:"update_time"`
}

func (info *BaseInfo) GetBaseInfo() *BaseInfo {
	return info
}

type BaseInfoSetter interface {
	GetBaseInfo() *BaseInfo
}

type BaseInfoGetter interface {
	GetBaseInfo() *BaseInfo
}

type Route struct {
	BaseInfo
	URI             string                 `json:"uri,omitempty"`
	Uris            []string               `json:"uris,omitempty"`
	Name            string                 `json:"name,omitempty" validate:"max=50"`
	Desc            string                 `json:"desc,omitempty" validate:"max=256"`
	Priority        int                    `json:"priority"`
	Methods         []string               `json:"methods,omitempty"`
	Host            string                 `json:"host,omitempty"`
	Hosts           []string               `json:"hosts,omitempty"`
	RemoteAddr      string                 `json:"remote_addr,omitempty"`
	RemoteAddrs     []string               `json:"remote_addrs,omitempty"`
	Vars            interface{}            `json:"vars,omitempty"`
	FilterFunc      string                 `json:"filter_func,omitempty"`
	Script          interface{}            `json:"script,omitempty"`
	Plugins         map[string]interface{} `json:"plugins,omitempty"`
	Upstream        *UpstreamDef           `json:"upstream,omitempty"` //
	ServiceID       string                 `json:"service_id,omitempty"`
	UpstreamID      string                 `json:"upstream_id,omitempty"`
	ServiceProtocol string                 `json:"service_protocol,omitempty"`
	Labels          map[string]string      `json:"labels,omitempty"`
}

// --- structures for upstream start  ---
type Timeout struct {
	Connect int `json:"connect,omitempty"`
	Send    int `json:"send,omitempty"`
	Read    int `json:"read,omitempty"`
}

type Node struct {
	Host     string      `json:"host,omitempty"`
	Port     int         `json:"port,omitempty"`
	Weight   int         `json:"weight,omitempty"`
	Metadata interface{} `json:"metadata,omitempty"`
}

type K8sInfo struct {
	Namespace   string `json:"namespace,omitempty"`
	DeployName  string `json:"deploy_name,omitempty"`
	ServiceName string `json:"service_name,omitempty"`
	Port        int    `json:"port,omitempty"`
	BackendType string `json:"backend_type,omitempty"`
}

type Healthy struct {
	Interval     int   `json:"interval,omitempty"`
	HttpStatuses []int `json:"http_statuses,omitempty"`
	Successes    int   `json:"successes,omitempty"`
}

type UnHealthy struct {
	Interval     int   `json:"interval,omitempty"`
	HTTPStatuses []int `json:"http_statuses,omitempty"`
	TCPFailures  int   `json:"tcp_failures,omitempty"`
	Timeouts     int   `json:"timeouts,omitempty"`
	HTTPFailures int   `json:"http_failures,omitempty"`
}

type Active struct {
	Type                   string    `json:"type,omitempty"`
	Timeout                int       `json:"timeout,omitempty"`
	Concurrency            int       `json:"concurrency,omitempty"`
	Host                   string    `json:"host,omitempty"`
	Port                   int       `json:"port,omitempty"`
	HTTPPath               string    `json:"http_path,omitempty"`
	HTTPSVerifyCertificate string    `json:"https_verify_certificate,omitempty"`
	Healthy                Healthy   `json:"healthy,omitempty"`
	UnHealthy              UnHealthy `json:"unhealthy,omitempty"`
	ReqHeaders             []string  `json:"req_headers,omitempty"`
}

type Passive struct {
	Type      string    `json:"type,omitempty"`
	Healthy   Healthy   `json:"healthy,omitempty"`
	UnHealthy UnHealthy `json:"unhealthy,omitempty"`
}

type HealthChecker struct {
	Active  Active  `json:"active,omitempty"`
	Passive Passive `json:"passive,omitempty"`
}

type UpstreamDef struct {
	Nodes           interface{}       `json:"nodes,omitempty"`
	Retries         int               `json:"retries,omitempty"`
	Timeout         interface{}       `json:"timeout,omitempty"`
	K8sInfo         interface{}       `json:"k8s_deployment_info,omitempty"`
	Type            string            `json:"type,omitempty"`
	Checks          interface{}       `json:"checks,omitempty"`
	HashOn          string            `json:"hash_on,omitempty"`
	Key             string            `json:"key,omitempty"`
	EnableWebsocket bool              `json:"enable_websocket,omitempty"`
	PassHost        string            `json:"pass_host,omitempty"`
	UpstreamHost    string            `json:"upstream_host,omitempty"`
	Name            string            `json:"name,omitempty"`
	Desc            string            `json:"desc,omitempty"`
	ServiceName     string            `json:"service_name,omitempty"` //添加后不需要node也可以走通
	Labels          map[string]string `json:"labels,omitempty"`
}

type Upstream struct {
	BaseInfo
	UpstreamDef
}

type UpstreamNameResponse struct {
	ID   string `json:"id"`
	Name string `json:"name"`
}

func (upstream *Upstream) Parse2NameResponse() (*UpstreamNameResponse, error) {
	nameResp := &UpstreamNameResponse{
		ID:   upstream.ID,
		Name: upstream.Name,
	}
	return nameResp, nil
}

// --- structures for upstream end  ---

type Consumer struct {
	BaseInfo
	Username string                 `json:"username"`
	Desc     string                 `json:"desc,omitempty"`
	Plugins  map[string]interface{} `json:"plugins,omitempty"`
	Labels   map[string]string      `json:"labels,omitempty"`
}

type SSL struct {
	BaseInfo
	Cert          string            `json:"cert,omitempty"`
	Key           string            `json:"key,omitempty"`
	Sni           string            `json:"sni,omitempty"`
	Snis          []string          `json:"snis,omitempty"`
	Certs         []string          `json:"certs,omitempty"`
	Keys          []string          `json:"keys,omitempty"`
	ExpTime       int64             `json:"exptime,omitempty"`
	Status        int               `json:"status"`
	ValidityStart int64             `json:"validity_start,omitempty"`
	ValidityEnd   int64             `json:"validity_end,omitempty"`
	Labels        map[string]string `json:"labels,omitempty"`
}

type Service struct {
	BaseInfo
	Name       string                 `json:"name,omitempty"` //id
	Desc       string                 `json:"desc,omitempty"`
	Upstream   *UpstreamDef           `json:"upstream,omitempty"`    //2选1
	UpstreamID string                 `json:"upstream_id,omitempty"` //2选1
	Plugins    map[string]interface{} `json:"plugins,omitempty"`
	Script     string                 `json:"script,omitempty"`
	Labels     map[string]string      `json:"labels,omitempty"`
}

type ServicePage struct {
	Services []*Service `json:"services"`
	Total    int        `json:"total"`
}

type RoutePage struct {
	Routes []*Route `json:"routes"`
	Total  int      `json:"total"`
}

type Script struct {
	ID     string      `json:"id"`
	Script interface{} `json:"script,omitempty"`
}

//声明一个Hero结构体切片类型
type ServiceSlice []*Service

//切片实现Interface 接口的三个方法
//1.Len() ：返回切片的大小
func (m ServiceSlice) Len() int {
	return len(m)
}

//2.Less(i, j int) :决定使用什么规则进行排序
func (m ServiceSlice) Less(i, j int) bool {
	return m[i].CreateTime > m[j].CreateTime
}

//3.Swap(i, j int) :Less(i, j int)返回true时进行交换
func (m ServiceSlice) Swap(i, j int) {
	m[i], m[j] = m[j], m[i]
}

//声明一个Hero结构体切片类型
type RouteSlice []*Route

//切片实现Interface 接口的三个方法
//1.Len() ：返回切片的大小
func (m RouteSlice) Len() int {
	return len(m)
}

//2.Less(i, j int) :决定使用什么规则进行排序
func (m RouteSlice) Less(i, j int) bool {
	return m[i].CreateTime > m[j].CreateTime
}

//3.Swap(i, j int) :Less(i, j int)返回true时进行交换
func (m RouteSlice) Swap(i, j int) {
	m[i], m[j] = m[j], m[i]
}
